package com.principles.behavior.interpreter;

/**
 * @Description 解释器模式：定义语言的文法，并且简历一个解释器来解释该语言中的句子，这里的”语言“是指使用规定格式和语法的代码。
 * @Date 2025/1/31 11:34
 **/
public class InterpreterPattern {
    // 规则：Robert 和 John 是男性
    public static Expression getMaleExpression(){
        Expression robert = new TerminalExpression("Robert");
        Expression john = new TerminalExpression("John");
        // 使用 OrExpression 进行 "或" 逻辑判断
        return new OrExpression(robert, john);
    }

    // 规则：Julie 是一个已婚的女性
    public static Expression getMarriedWomanExpression(){
        Expression julie = new TerminalExpression("Julie");
        Expression married = new TerminalExpression("Married");
        // 使用 AndExpression 进行 "与" 逻辑判断
        return new AndExpression(julie, married);
    }

    public static void main(String[] args) {
        Expression isMale = getMaleExpression();
        Expression isMarriedWoman = getMarriedWomanExpression();

        // 测试 "John" 是否是男性
        System.out.println("John is male? " + isMale.interpret("John"));

        // 测试 "Julie" 是否是已婚女性
        System.out.println("Julie is a married woman? "
                + isMarriedWoman.interpret("Married Julie"));
    }
}

// 解释器接口，所有表达式都需要实现 interpret 方法
interface Expression {
    boolean interpret(String context);
}

// 终结符表达式（具体的单词匹配规则）
class TerminalExpression implements Expression {
    private String data;

    public TerminalExpression(String data){
        this.data = data;
    }

    @Override
    public boolean interpret(String context) {
        // 如果输入字符串包含指定的单词，则返回 true
        return context.contains(data);
    }
}

// "或" 表达式（满足任意一个规则）
class OrExpression implements Expression {
    private Expression expr1;
    private Expression expr2;

    public OrExpression(Expression expr1, Expression expr2) {
        this.expr1 = expr1;
        this.expr2 = expr2;
    }

    @Override
    public boolean interpret(String context) {
        // 只要满足其中一个表达式就返回 true
        return expr1.interpret(context) || expr2.interpret(context);
    }
}

// "与" 表达式（必须满足所有规则）
class AndExpression implements Expression {
    private Expression expr1;
    private Expression expr2;

    public AndExpression(Expression expr1, Expression expr2) {
        this.expr1 = expr1;
        this.expr2 = expr2;
    }

    @Override
    public boolean interpret(String context) {
        // 只有同时满足两个表达式时才返回 true
        return expr1.interpret(context) && expr2.interpret(context);
    }
}
